package org.fle4y.app.server.database;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.sql.SQLException;


/**
 * author : xiehui<br>
 * company : northking <br>
 * Create at: 2012-6-20<br>
 * @version : 1.0<br>
 * mailto:flexie@foxmail.com<br>
 *  Description : 结果集
 */
public class Result {
	  	private Record   rTail;
	    private int      iSize;
	    private int      iColumnCount;
	    final static int UPDATECOUNT = 0, ERROR = 1, DATA = 2;
	    int		     iMode;
	    String	     sError;
	    int		     iUpdateCount;
	    Record	     rRoot;
	    String	     sLabel[];
	    String	     sTable[];
	    String	     sName[];
	    int		     iType[];
	    
	    public Result() {
		iMode = UPDATECOUNT;
		iUpdateCount = 0;
	    }
	    
	    public Result(String error) {
		iMode = ERROR;
		sError = error;
	    }
	    
	    public Result(int columns) {
		prepareData(columns);

		iColumnCount = columns;
	    }

	    public int getSize() {
		return iSize;
	    }

	    public void setColumnCount(int columns) {
		iColumnCount = columns;
	    }

	    public int getColumnCount() {
		return iColumnCount;
	    }

	    public void append(Result a) {
		if (rRoot == null) {
		    rRoot = a.rRoot;
		} else {
		    rTail.next = a.rRoot;
		}

		rTail = a.rTail;
		iSize += a.iSize;
	    }

	    /**
	     * Method declaration
	     *
	     *
	     * @param d
	     */
	    public void add(Object d[]) {
		Record r = new Record();

		r.data = d;

		if (rRoot == null) {
		    rRoot = r;
		} else {
		    rTail.next = r;
		}

		rTail = r;
		iSize++;
	    }

	    /**
	     * Constructor declaration
	     *
	     *
	     * @param b
	     */
	    public Result(byte b[]) throws SQLException {
		ByteArrayInputStream bin = new ByteArrayInputStream(b);
		DataInputStream      in = new DataInputStream(bin);

		try {
		    iMode = in.readInt();

		    if (iMode == ERROR) {
			throw new SQLException("读取错误");
		    } else if (iMode == UPDATECOUNT) {
			iUpdateCount = in.readInt();
		    } else if (iMode == DATA) {
			int l = in.readInt();

			prepareData(l);

			iColumnCount = l;

			for (int i = 0; i < l; i++) {
			    iType[i] = in.readInt();
			    sLabel[i] = in.readUTF();
			    sTable[i] = in.readUTF();
			    sName[i] = in.readUTF();
			}

			while (in.available() != 0) {
			    add(Column.readData(in, l));
			}
		    }
		} catch (IOException e) {
			throw new SQLException("传输被中断s");
		}
	    }

	    byte[] getBytes() throws SQLException {
		ByteArrayOutputStream bout = new ByteArrayOutputStream();
		DataOutputStream      out = new DataOutputStream(bout);

		try {
		    out.writeInt(iMode);

		    if (iMode == UPDATECOUNT) {
			out.writeInt(iUpdateCount);
		    } else if (iMode == ERROR) {
			out.writeUTF(sError);
		    } else {
			int l = iColumnCount;

			out.writeInt(l);

			Record n = rRoot;

			for (int i = 0; i < l; i++) {
			    out.writeInt(iType[i]);
			    out.writeUTF(sLabel[i]);
			    out.writeUTF(sTable[i]);
			    out.writeUTF(sName[i]);
			}

			while (n != null) {
			    Column.writeData(out, l, iType, n.data);
			    n = n.next;
			}
		    }

		    return bout.toByteArray();
		} catch (IOException e) {
		    throw new SQLException("传输被中断 !");
		}
	    }

	    /**
	     * Method declaration
	     *
	     *
	     * @param columns
	     */
	    private void prepareData(int columns) {
		iMode = DATA;
		sLabel = new String[columns];
		sTable = new String[columns];
		sName = new String[columns];
		iType = new int[columns];
	    }
}
